home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / midas060 / src / gmplayer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-16  |  81.3 KB  |  2,408 lines

  1. /*      gmplayer.c
  2.  *
  3.  * Generic Module Player
  4.  *
  5.  * $Id: gmplayer.c,v 1.12 1997/01/16 18:41:59 pekangas Exp $
  6.  *
  7.  * Copyright 1996,1997 Housemarque Inc.
  8.  *
  9.  * This file is part of the MIDAS Sound System, and may only be
  10.  * used, modified and distributed under the terms of the MIDAS
  11.  * Sound System license, LICENSE.TXT. By continuing to use,
  12.  * modify or distribute this file you indicate that you have
  13.  * read the license and understand and accept it fully.
  14. */
  15.  
  16. /*#define DEBUGMESSAGES */
  17.  
  18. #ifdef DEBUGMESSAGES
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #endif
  22.  
  23. #include "lang.h"
  24. #include "mtypes.h"
  25. #include "errors.h"
  26. #include "sdevice.h"
  27. #include "gmplayer.h"
  28. #include "mmem.h"
  29.  
  30. #ifdef DEBUGMESSAGES
  31. #define DEBUGprintf(x,y) printf(x,y)
  32. #define DEBUGputs(x) puts(x)
  33. #else
  34. #define DEBUGprintf(x,y)
  35. #define DEBUGputs(x)
  36. #endif
  37.  
  38. RCSID(const char *gmplayer_rcsid = "$Id: gmplayer.c,v 1.12 1997/01/16 18:41:59 pekangas Exp $";)
  39.  
  40.  
  41. static volatile int  gmpNoPlay = 0;     /* 1 if music should NOT be played */
  42. SoundDevice     *gmpSD;                 /* Sound Device used by GMP */
  43. gmpChannel      *gmpChan;               /* current GMP channel */
  44. unsigned        gmpTempo;               /* GMP playing tempo (global for
  45.                                            all songs) */
  46. unsigned        gmpPlayMode;            /* current playing mode */
  47. gmpPlayHandle   gmpHandle;              /* current playing handle */
  48. gmpModule       *gmpCurModule;          /* current playing module */
  49. static gmpPlayHandle playHandles[MAXSONGS];     /* playing handles */
  50. static int (CALLING *SetUpdRate)(unsigned updRate);
  51.                                         /* pointer to update rate changing
  52.                                            function */
  53.  
  54.  
  55.     /* Period values for octave 0 notes for all finetune values in Protracker
  56.        modules: */
  57. static unsigned gmpPeriodsPT[16*12] = {
  58.         /* Tuning 0: */
  59.         1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,907,
  60.         /* Tuning 1: */
  61.         1700,1604,1514,1430,1348,1274,1202,1134,1070,1010,954,900,
  62.         /* Tuning 2: */
  63.         1688,1592,1504,1418,1340,1264,1194,1126,1064,1004,948,894,
  64.         /* Tuning 3: */
  65.         1676,1582,1492,1408,1330,1256,1184,1118,1056,996,940,888,
  66.         /* Tuning 4: */
  67.         1664,1570,1482,1398,1320,1246,1176,1110,1048,990,934,882,
  68.         /* Tuning 5: */
  69.         1652,1558,1472,1388,1310,1238,1168,1102,1040,982,926,874,
  70.         /* Tuning 6: */
  71.         1640,1548,1460,1378,1302,1228,1160,1094,1032,974,920,868,
  72.         /* Tuning 7: */
  73.         1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914,862,
  74.         /* Tuning -8: */
  75.         1814,1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,
  76.         /* Tuning -7: */
  77.         1800,1700,1604,1514,1430,1350,1272,1202,1134,1070,1010,954,
  78.         /* Tuning -6: */
  79.         1788,1688,1592,1504,1418,1340,1264,1194,1126,1064,1004,948,
  80.         /* Tuning -5: */
  81.         1774,1676,1582,1492,1408,1330,1256,1184,1118,1056,996,940,
  82.         /* Tuning -4: */
  83.         1762,1664,1570,1482,1398,1320,1246,1176,1110,1048,988,934,
  84.         /* Tuning -3: */
  85.         1750,1652,1558,1472,1388,1310,1238,1168,1102,1040,982,926,
  86.         /* Tuning -2: */
  87.         1736,1640,1548,1460,1378,1302,1228,1160,1094,1032,974,920,
  88.         /* Tuning -1: */
  89.         1724,1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914 };
  90.  
  91.     /* Period table for Fasttracker 2 module playing: */
  92. static unsigned gmpPeriodsFT2[96+8] = {
  93.         907,900,894,887,881,875,868,862,856,850,844,838,832,826,820,814,
  94.         808,802,796,791,785,779,774,768,762,757,752,746,741,736,730,725,
  95.         720,715,709,704,699,694,689,684,678,675,670,665,660,655,651,646,
  96.         640,636,632,628,623,619,614,610,604,601,597,592,588,584,580,575,
  97.         570,567,563,559,555,551,547,543,538,535,532,528,524,520,516,513,
  98.         508,505,502,498,494,491,487,484,480,477,474,470,467,463,460,457,
  99.         453,450,447,443,440,437,434,431 };
  100.  
  101.     /* Period table for Screamtracker 3 module playing: */
  102. static unsigned gmpPeriodsST3[12] = {
  103.         1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,907 };
  104.  
  105.  
  106.     /* Magic table for Fasttracker 2 linear frequency support: (don't ask me
  107.        what this is - I ripped it from Jarno's PS3M source (PK)) */
  108. static unsigned long gmpLinTable[768] = {
  109.         535232,534749,534266,533784,533303,532822,532341,531861,
  110.         531381,530902,530423,529944,529466,528988,528511,528034,
  111.         527558,527082,526607,526131,525657,525183,524709,524236,
  112.         523763,523290,522818,522346,521875,521404,520934,520464,
  113.         519994,519525,519057,518588,518121,517653,517186,516720,
  114.         516253,515788,515322,514858,514393,513929,513465,513002,
  115.         512539,512077,511615,511154,510692,510232,509771,509312,
  116.         508852,508393,507934,507476,507018,506561,506104,505647,
  117.         505191,504735,504280,503825,503371,502917,502463,502010,
  118.         501557,501104,500652,500201,499749,499298,498848,498398,
  119.         497948,497499,497050,496602,496154,495706,495259,494812,
  120.         494366,493920,493474,493029,492585,492140,491696,491253,
  121.         490809,490367,489924,489482,489041,488600,488159,487718,
  122.         487278,486839,486400,485961,485522,485084,484647,484210,
  123.         483773,483336,482900,482465,482029,481595,481160,480726,
  124.         480292,479859,479426,478994,478562,478130,477699,477268,
  125.         476837,476407,475977,475548,475119,474690,474262,473834,
  126.         473407,472979,472553,472126,471701,471275,470850,470425,
  127.         470001,469577,469153,468730,468307,467884,467462,467041,
  128.         466619,466198,465778,465358,464938,464518,464099,463681,
  129.         463262,462844,462427,462010,461593,461177,460760,460345,
  130.         459930,459515,459100,458686,458272,457859,457446,457033,
  131.         456621,456209,455797,455386,454975,454565,454155,453745,
  132.         453336,452927,452518,452110,451702,451294,450887,450481,
  133.         450074,449668,449262,448857,448452,448048,447644,447240,
  134.         446836,446433,446030,445628,445226,444824,444423,444022,
  135.         443622,443221,442821,442422,442023,441624,441226,440828,
  136.         440430,440033,439636,439239,438843,438447,438051,437656,
  137.         437261,436867,436473,436079,435686,435293,434900,434508,
  138.         434116,433724,433333,432942,432551,432161,431771,431382,
  139.         430992,430604,430215,429827,429439,429052,428665,428278,
  140.         427892,427506,427120,426735,426350,425965,425581,425197,
  141.         424813,424430,424047,423665,423283,422901,422519,422138,
  142.         421757,421377,420997,420617,420237,419858,419479,419101,
  143.         418723,418345,417968,417591,417214,416838,416462,416086,
  144.         415711,415336,414961,414586,414212,413839,413465,413092,
  145.         412720,412347,411975,411604,411232,410862,410491,410121,
  146.         409751,409381,409012,408643,408274,407906,407538,407170,
  147.         406803,406436,406069,405703,405337,404971,404606,404241,
  148.         403876,403512,403148,402784,402421,402058,401695,401333,
  149.         400970,400609,400247,399886,399525,399165,398805,398445,
  150.         398086,397727,397368,397009,396651,396293,395936,395579,
  151.         395222,394865,394509,394153,393798,393442,393087,392733,
  152.         392378,392024,391671,391317,390964,390612,390259,389907,
  153.         389556,389204,388853,388502,388152,387802,387452,387102,
  154.         386753,386404,386056,385707,385359,385012,384664,384317,
  155.         383971,383624,383278,382932,382587,382242,381897,381552,
  156.         381208,380864,380521,380177,379834,379492,379149,378807,
  157.         378466,378124,377783,377442,377102,376762,376422,376082,
  158.         375743,375404,375065,374727,374389,374051,373714,373377,
  159.         373040,372703,372367,372031,371695,371360,371025,370690,
  160.         370356,370022,369688,369355,369021,368688,368356,368023,
  161.         367691,367360,367028,366697,366366,366036,365706,365376,
  162.         365046,364717,364388,364059,363731,363403,363075,362747,
  163.         362420,362093,361766,361440,361114,360788,360463,360137,
  164.         359813,359488,359164,358840,358516,358193,357869,357547,
  165.         357224,356902,356580,356258,355937,355616,355295,354974,
  166.         354654,354334,354014,353695,353376,353057,352739,352420,
  167.         352103,351785,351468,351150,350834,350517,350201,349885,
  168.         349569,349254,348939,348624,348310,347995,347682,347368,
  169.         347055,346741,346429,346116,345804,345492,345180,344869,
  170.         344558,344247,343936,343626,343316,343006,342697,342388,
  171.         342079,341770,341462,341154,340846,340539,340231,339924,
  172.         339618,339311,339005,338700,338394,338089,337784,337479,
  173.         337175,336870,336566,336263,335959,335656,335354,335051,
  174.         334749,334447,334145,333844,333542,333242,332941,332641,
  175.         332341,332041,331741,331442,331143,330844,330546,330247,
  176.         329950,329652,329355,329057,328761,328464,328168,327872,
  177.         327576,327280,326985,326690,326395,326101,325807,325513,
  178.         325219,324926,324633,324340,324047,323755,323463,323171,
  179.         322879,322588,322297,322006,321716,321426,321136,320846,
  180.         320557,320267,319978,319690,319401,319113,318825,318538,
  181.         318250,317963,317676,317390,317103,316817,316532,316246,
  182.         315961,315676,315391,315106,314822,314538,314254,313971,
  183.         313688,313405,313122,312839,312557,312275,311994,311712,
  184.         311431,311150,310869,310589,310309,310029,309749,309470,
  185.         309190,308911,308633,308354,308076,307798,307521,307243,
  186.         306966,306689,306412,306136,305860,305584,305308,305033,
  187.         304758,304483,304208,303934,303659,303385,303112,302838,
  188.         302565,302292,302019,301747,301475,301203,300931,300660,
  189.         300388,300117,299847,299576,299306,299036,298766,298497,
  190.         298227,297958,297689,297421,297153,296884,296617,296349,
  191.         296082,295815,295548,295281,295015,294749,294483,294217,
  192.         293952,293686,293421,293157,292892,292628,292364,292100,
  193.         291837,291574,291311,291048,290785,290523,290261,289999,
  194.         289737,289476,289215,288954,288693,288433,288173,287913,
  195.         287653,287393,287134,286875,286616,286358,286099,285841,
  196.         285583,285326,285068,284811,284554,284298,284041,283785,
  197.         283529,283273,283017,282762,282507,282252,281998,281743,
  198.         281489,281235,280981,280728,280475,280222,279969,279716,
  199.         279464,279212,278960,278708,278457,278206,277955,277704,
  200.         277453,277203,276953,276703,276453,276204,275955,275706,
  201.         275457,275209,274960,274712,274465,274217,273970,273722,
  202.         273476,273229,272982,272736,272490,272244,271999,271753,
  203.         271508,271263,271018,270774,270530,270286,270042,269798,
  204.         269555,269312,269069,268826,268583,268341,268099,267857 };
  205.  
  206. static signed char ft2VibratoTable[256] = {
  207.         0,-2,-3,-5,-6,-8,-9,-11,-12,-14,-16,-17,-19,-20,-22,-23,
  208.         -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,
  209.         -43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,
  210.         -56,-57,-58,-59,-59,-60,-60,-61,-61,-62,-62,-62,-63,-63,
  211.         -63,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-63,-63,
  212.         -63,-62,-62,-62,-61,-61,-60,-60,-59,-59,-58,-57,-56,-56,
  213.         -55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,
  214.         -41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26,-24,-23,
  215.         -22,-20,-19,-17,-16,-14,-12,-11,-9,-8,-6,-5,-3,-2,0,
  216.         2,3,5,6,8,9,11,12,14,16,17,19,20,22,23,24,26,27,29,30,
  217.         32,33,34,36,37,38,39,41,42,43,44,45,46,47,48,49,50,51,
  218.         52,53,54,55,56,56,57,58,59,59,60,60,61,61,62,62,62,63,
  219.         63,63,64,64,64,64,64,64,64,64,64,64,64,63,63,63,62,62,
  220.         62,61,61,60,60,59,59,58,57,56,56,55,54,53,52,51,50,49,
  221.         48,47,46,45,44,43,42,41,39,38,37,36,34,33,32,30,29,27,
  222.         26,24,23,22,20,19,17,16,14,12,11,9,8,6,5,3,2 };
  223.  
  224.         /* Flags for FT2 commands - 1 if previous infobyte should be used when
  225.            the infobyte is 0: */
  226. static uchar    ft2UsePrevInfo[gmpNumCommands] =
  227.     {
  228.         0,    /* no command */
  229.         0,    /* arpeggio */
  230.         1,    /* period slide up */
  231.         1,    /* period slide down */
  232.         0,    /* tone portamento */                 /* handled by command */
  233.         0,    /* vibrato */                         /* handled by command */
  234.         0,    /* tone portamento + volume slide */  /* handled by command */
  235.         0,    /* vibrato + volume slide */          /* handled by command */
  236.         0,    /* tremolo */                         /* handled by command */
  237.         0,    /* set panning (PT cmd 8) */
  238.         0,    /* set sample offset */               /* handled by command */
  239.         0,    /* volume slide */                    /* handled by command */
  240.         0,    /* position jump */
  241.         0,    /* set volume */
  242.         0,    /* pattern break (to a row) */
  243.         0,    /* set speed */
  244.         0,    /* set tempo in BPM */
  245.         1,    /* fine period slide up */
  246.         1,    /* fine period slide down */
  247.         0,    /* pattern loop set/loop */
  248.         0,    /* set 16-point panning value */
  249.         0,    /* Protracker-style retrig note */
  250.         1,    /* fine volume slide up */
  251.         1,    /* fine volume slide down */
  252.         0,    /* note cut */
  253.         0,    /* note delay */
  254.         0,    /* pattern delay */
  255.         0,    /* set master volume */
  256.         1,    /* master volume slide */
  257.         0,    /* S3M retrig note */
  258.         0,    /* music synchronization command */
  259.         1,    /* extra fine period slide up */
  260.         1,    /* extra fine period slide down */
  261.         0    /* panning slide */
  262.     };
  263.  
  264. /* Local prototypes: */
  265. int gmpPlayPattern(gmpPlayHandle playHandle);
  266. int gmpHandleCommands(gmpPlayHandle playHandle);
  267. int gmpRunEnvelopes(gmpPlayHandle playHandle);
  268.  
  269.  
  270.  
  271. /****************************************************************************\
  272. *
  273. * Function:     int gmpInit(SoundDevice *SD);
  274. *
  275. * Description:  Initializes Generic Module Player
  276. *
  277. * Input:        SoundDevice *SD         Pointer to the Sound Device that will
  278. *                                       be used for playing the music
  279. *
  280. * Returns:      MIDAS error code
  281. *
  282. \****************************************************************************/
  283.  
  284. int CALLING gmpInit(SoundDevice *SD)
  285. {
  286.     int         i;
  287.     int         error;
  288.  
  289.     /* Store Sound Device pointer: */
  290.     gmpSD = SD;
  291.  
  292.     /* Point all playing handles to NULL to mark them free: */
  293.     for ( i = 0; i < MAXSONGS; i++ )
  294.         playHandles[i] = NULL;
  295.  
  296.     /* Point SetUpdRate() to NULL to mark it has not been set: */
  297.     SetUpdRate = NULL;
  298.  
  299.     /* Set tempo by default to 125 and set Sound Device updating rate
  300.        accordingly: */
  301.     if ( (error = gmpSetTempo(125)) != OK )
  302.         PASSERROR(ID_gmpInit);
  303.  
  304.     return OK;
  305. }
  306.  
  307.  
  308.  
  309.  
  310. /****************************************************************************\
  311. *
  312. * Function:     int gmpClose(void);
  313. *
  314. * Description:  Uninitializes Generic Module Player
  315. *
  316. * Returns:      MIDAS error code
  317. *
  318. \****************************************************************************/
  319.  
  320. int CALLING gmpClose(void)
  321. {
  322.     int         i;
  323.     int         error;
  324.  
  325.     /* Stop all still playing songs: */
  326.     for ( i = 0; i < MAXSONGS; i++ )
  327.     {
  328.         if ( playHandles[i] != NULL )
  329.         {
  330.             if ( (error = gmpStopSong(playHandles[i])) != OK )
  331.                 PASSERROR(ID_gmpClose)
  332.         }
  333.     }
  334.  
  335.     return OK;
  336. }
  337.  
  338.  
  339.  
  340.  
  341. /****************************************************************************\
  342. *
  343. * Function:     int gmpSetUpdRateFunct(int (*SetUpdRate)(unsigned updRate));
  344. *
  345. * Description:  Changes the function that will be used to change the playing
  346. *               update rate. Every time song tempo changes, SetUpdRate()
  347. *               will be called with the new player tick rate (in 100*Hz).
  348. *
  349. * Input:        int (*SetUpdRate)(unsigned updRate)   Pointer to updating rate
  350. *                                                     changing function.
  351. *
  352. * Returns:      MIDAS error code
  353. *
  354. * Notes:        SetUpdRate usually points to tmrSetUpdRate(). GMPlayer
  355. *               automatically sets the correct updating rate to the Sound
  356. *               Device used.
  357. *
  358. \****************************************************************************/
  359.  
  360. int CALLING gmpSetUpdRateFunct(int (CALLING *_SetUpdRate)(unsigned updRate))
  361. {
  362.     int         error;
  363.  
  364.     /* Save update rate changing function: */
  365.     SetUpdRate = _SetUpdRate;
  366.  
  367.     if ( SetUpdRate != NULL )
  368.     {
  369.         /* Set update rate to match current tempo: */
  370.         if ( (error = SetUpdRate(40*gmpTempo)) != OK )
  371.             PASSERROR(ID_gmpSetUpdRateFunct)
  372.     }
  373.  
  374.     return OK;
  375. }
  376.  
  377.  
  378.  
  379.  
  380. /****************************************************************************\
  381. *
  382. * Function:     int gmpPlaySong(gmpModule *module, int startPos, int endPos,
  383. *                   int restartPos, int numChannels,
  384. *                   gmpPlayHandle *playHandle)
  385. *
  386. * Description:  Starts playing a song from a module
  387. *
  388. * Input:        gmpModule *module       pointer to module to be played
  389. *               int startPos            song start position
  390. *               int endPos              song end position
  391. *               int restartPos          song restart position
  392. *               int numChannels         number of channels to be played
  393. *               unsigned *sdChannels    pointer to an array of Sound Device
  394. *                                       channel numbers for all channels that
  395. *                                       are required for playing
  396. *               gmpPlayHandle *playHandle   pointer to GMP playing handle
  397. *
  398. * Returns:      MIDAS error code. Playing handle for this song is written to
  399. *               *playHandle.
  400. *
  401. * Notes:        To play the whole module, set startPos, endPos, restartPos and
  402. *               numChannels to -1.
  403. *
  404. \****************************************************************************/
  405.  
  406. int CALLING gmpPlaySong(gmpModule *module, int startPos, int endPos,
  407.     int restartPos, int numChannels, unsigned *sdChannels,
  408.     gmpPlayHandle *playHandle)
  409. {
  410.     static gmpPlayHandle  handle;
  411.     int         error, i, hnum, c;
  412.     int         numChs;
  413.     gmpChannel  *chan;
  414.  
  415.     /* Check if number of channels has been specified, and if not, use the
  416.        full number of channels from module: */
  417.     if ( numChannels != -1 )
  418.         numChs = numChannels;
  419.     else
  420.         numChs = module->numChannels;
  421.  
  422.     /* Find first free position from playing handle table: */
  423.     hnum = -1;
  424.     for ( i = 0; i < MAXSONGS; i++ )
  425.     {
  426.         if ( playHandles[i] == NULL )
  427.             hnum = i;
  428.     }
  429.  
  430.     /* If there are no free playing handles, return error: */
  431.     if ( hnum == -1 )
  432.     {
  433.         ERROR(errOutOfResources, ID_gmpPlaySong);
  434.         return errOutOfResources;
  435.     }
  436.  
  437.     /* Don't play while we are setting up the channels: */
  438.     gmpNoPlay = 1;
  439.  
  440.     /* Allocate memory for new playing handle: */
  441.     if ( (error = memAlloc(sizeof(gmpPlayStatus), (void**) &handle)) != OK )
  442.         PASSERROR(ID_gmpPlaySong)
  443.  
  444.     /* Point channel structure pointer to NULL for safety: */
  445.     handle->channels = NULL;
  446.  
  447.     playHandles[hnum] = handle;
  448.     handle->handleNum = hnum;
  449.  
  450.     /* Allocate memory for channel structures: */
  451.     if ( (error = memAlloc(numChs * sizeof(gmpChannel), (void**)
  452.         &handle->channels)) != OK)
  453.         PASSERROR(ID_gmpPlaySong)
  454.  
  455.     /* Set up initial values for playing status structure: */
  456.     handle->module = module;
  457.     handle->playPtr = NULL;
  458.     handle->tempo = module->tempo;
  459.     handle->speed = module->speed;
  460.     handle->playCount = 0;
  461.     handle->numChannels = numChs;
  462.     handle->row = 0;
  463.     handle->pattDelayCount = 0;
  464.     handle->SyncCallback = NULL;
  465.     handle->syncInfo = -1;
  466.     handle->loopRow = handle->loopCount = 0;
  467.     handle->masterVolume = module->masterVolume;
  468.     gmpTempo = handle->tempo;
  469.  
  470.     /* Set song initial tempo: */
  471.     if ( (error = gmpSetTempo(handle->tempo)) != OK )
  472.         PASSERROR(ID_gmpPlaySong)
  473.  
  474.     /* Check if song playing range has been specified, and if not, play
  475.        whole module: */
  476.     if ( startPos != -1 )
  477.     {
  478.         handle->position = startPos;
  479.         handle->songEnd = endPos;
  480.         handle->restartPos = restartPos;
  481.     }
  482.     else
  483.     {
  484.         handle->position = 0;
  485.         handle->songEnd = module->songLength - 1;
  486.         handle->restartPos = module->restart;
  487.     }
  488.  
  489.     handle->pattern = module->songData[handle->position];
  490.  
  491.     /* Clear channel structures to their initial states: */
  492.     chan = handle->channels;
  493.     /* Set gmpPlayMode to current playing mode: */
  494.     gmpPlayMode = module->playMode;
  495.  
  496.     for ( i = 0; i < numChs; i++ )
  497.     {
  498.         gmpChan = chan;
  499.         gmpHandle = handle;
  500.  
  501.         chan->command = gmpcNone;       /* no command */
  502.         chan->infobyte = 0;             /* no infobyte */
  503.         chan->oldInfo = 0;              /* no old infobyte */
  504.         chan->period = 0;               /* no period set */
  505.         chan->realPeriod = 0;
  506.         chan->truePeriod = 0;
  507.         chan->tpDest = 0;               /* no tone portamento destination */
  508.         chan->tpSpeed = 0;              /* no tone portamento speed */
  509.         chan->instrument = -1;          /* no instrument set */
  510.         chan->newInstrument = -1;       /* no new instrument set */
  511.         chan->sample = 0xFF;
  512.         chan->note = 0xFF;              /* no note set */
  513.         chan->prevNote = 0xFF;          /* there has been no note */
  514.         chan->startOffset = 0;          /* start from beginning of sample */
  515.         chan->sdChannel = (uchar) sdChannels[i];    /* SD channel number */
  516.         chan->volume = 64;              /* initial volume is 64 */
  517.         chan->realVolume = 64;          /* initial volume is 64 */
  518.         chan->keyOff = 0;               /* no key off -note yet */
  519.         chan->vibSpeed = 0;             /* clear vibrato speed */
  520.         chan->vibDepth = 0;             /* clear vibrato depth */
  521.         chan->vibPos = 0;               /* reset vibrato position */
  522.         chan->autoVibPos = 0;           /* auto vibrato position */
  523.         chan->autoVibDepth = 0;         /* auto vibrato depth */
  524.         chan->smpOffset = 0;            /* reset sample offset infobyte */
  525.         chan->loopRow = 0;
  526.         chan->loopCount = 0;
  527.         chan->volSlideInfobyte = 0;
  528.  
  529.         /* Clear old infobytes: */
  530.         for ( c = 0; c < gmpNumCommands; chan->oldInfobytes[c++] = 0 );
  531.  
  532.         /* Set channel initial panning position: */
  533.         if ( (error = gmpSetPanning(module->panning[i])) != OK )
  534.         {
  535.             gmpNoPlay = 0;
  536.             PASSERROR(ID_gmpPlaySong)
  537.         }
  538.         chan++;
  539.     }
  540.  
  541.     /* Set correct period limits: */
  542.     switch ( module->playMode )
  543.     {
  544.         case gmpPT:
  545.             handle->perMultiplier = 0;
  546.             handle->volLimit = 64;
  547.             if ( module->playFlags.extOctaves )
  548.             {
  549.                 /* Protracker module with extended octaves enabled: */
  550.                 handle->perLimitUp = 1712;
  551.                 handle->perLimitLow = 28;
  552.             }
  553.             else
  554.             {
  555.                 /* Protracker module with extended octaves disabled: */
  556.                 handle->perLimitUp = 856;
  557.                 handle->perLimitLow = 113;
  558.             }
  559.             break;
  560.  
  561.         case gmpFT2:
  562.             /* Fasttracker 2 period limits: (??) */
  563.             handle->perMultiplier = 2;
  564.             handle->volLimit = 64;
  565.             handle->perLimitUp = 54784;
  566.             handle->perLimitLow = 57;
  567.             break;
  568.  
  569.         case gmpST3:
  570.             /* Screamtracker 3 period limits: */
  571.             handle->perMultiplier = 2;
  572.             handle->volLimit = 63;
  573.             if ( module->playFlags.ptLimits )
  574.             {
  575.                 handle->perLimitUp = 856 << 2;
  576.                 handle->perLimitLow = 113 << 2;
  577.             }
  578.             else
  579.                 handle->perLimitUp = 0x7fff;
  580.                 handle->perLimitLow = 64;
  581.             break;
  582.     }
  583.  
  584.     /* Allocate memory for playing information structure: */
  585.     if ( (error = memAlloc(sizeof(gmpInformation), (void**)
  586.         &handle->information)) != OK )
  587.         PASSERROR(ID_gmpPlaySong)
  588.  
  589.     /* Set information structure channel pointer to channel structures: */
  590.     handle->information->channels = handle->channels;
  591.  
  592.     /* Reset information structure values: */
  593.     handle->information->position = handle->position;
  594.     handle->information->pattern = handle->pattern;
  595.     handle->information->row = handle->row;
  596.     handle->information->tempo = gmpTempo;
  597.     handle->information->speed = handle->speed;
  598.  
  599.     /* We can play again: */
  600.     gmpNoPlay = 0;
  601.  
  602.     /* Return new playing handle in *playHandle: */
  603.     *playHandle = handle;
  604.  
  605.     return OK;
  606. }
  607.  
  608.  
  609.  
  610.  
  611. /****************************************************************************\
  612. *
  613. * Function:     int gmpStopSong(gmpPlayHandle playHandle)
  614. *
  615. * Description:  Stops playing a song
  616. *
  617. * Input:        gmpPlayHandle playHandle   playing handle returned by
  618. *                                          gmpPlaySong().
  619. *
  620. * Returns:      MIDAS error code
  621. *
  622. \****************************************************************************/
  623.  
  624. int CALLING gmpStopSong(gmpPlayHandle playHandle)
  625. {
  626.     int         error;
  627.  
  628.     /* Deallocate channel structures if allocated: */
  629.     if ( playHandle->channels != NULL )
  630.     {
  631.         if ( (error = memFree(playHandle->channels)) != OK )
  632.             PASSERROR(ID_gmpStopSong)
  633.     }
  634.  
  635.     /* Mark playing handle free in table: */
  636.     playHandles[playHandle->handleNum] = NULL;
  637.  
  638.     /* Deallocate playing handle: */
  639.     if ( (error = memFree(playHandle)) != OK )
  640.         PASSERROR(ID_gmpStopSong)
  641.  
  642.     return OK;
  643. }
  644.  
  645.  
  646.  
  647.  
  648. /****************************************************************************\
  649. *
  650. * Function:     int gmpFreeModule(gmpModule *module)
  651. *
  652. * Description:  Deallocates a module structure allocated by a module loader
  653. *
  654. * Input:        gmpModule *module       module to be deallocated
  655. *
  656. * Returns:      MIDAS error code
  657. *
  658. \****************************************************************************/
  659.  
  660. int CALLING gmpFreeModule(gmpModule *module)
  661. {
  662.     int         error;
  663.     gmpInstrument *inst;
  664.     unsigned    i, s;
  665.  
  666.     if ( module == NULL )
  667.         return OK;
  668.  
  669.     DEBUGputs("gmpFreeModule");
  670.     DEBUGputs("module->panning");
  671.  
  672.     /* Deallocate initial channel panning positions if allocated: */
  673.     if ( module->panning != NULL )
  674.     {
  675.         if ( (error = memFree(module->panning)) != OK )
  676.             PASSERROR(ID_gmpFreeModule)
  677.     }
  678.  
  679.     DEBUGputs("module->songData");
  680.  
  681.     /* Deallocate song data if allocated: */
  682.     if ( module->songData != NULL )
  683.     {
  684.         if ( (error = memFree(module->songData)) != OK )
  685.             PASSERROR(ID_gmpFreeModule)
  686.     }
  687.  
  688.     /* Deallocate instruments if allocated: */
  689.     if ( module->instruments != NULL )
  690.     {
  691.         for ( i = 0; i < module->numInsts; i++ )
  692.         {
  693.             inst = module->instruments[i];
  694.             if ( inst != NULL )
  695.             {
  696.                 DEBUGprintf("inst[%i]->noteSamples\n", i);
  697.                 /* If the instrument has keyboard note sample list, deallocate
  698.                    it: */
  699.                 if ( inst->noteSamples != NULL )
  700.                 {
  701.                     if ( (error = memFree(inst->noteSamples)) != OK )
  702.                         PASSERROR(ID_gmpFreeModule)
  703.                 }
  704.  
  705.                 DEBUGprintf("inst[%i]->volEnvelope\n", i);
  706.                 /* If the instrument has volume envelope, deallocate it: */
  707.                 if ( inst->volEnvelope != NULL )
  708.                 {
  709.                     if ( (error = memFree(inst->volEnvelope)) != OK )
  710.                         PASSERROR(ID_gmpFreeModule)
  711.                 }
  712.  
  713.                 DEBUGprintf("inst[%i]->panEnvelope\n", i);
  714.                 /* If the instrument has panning envelope, deallocate it: */
  715.                 if ( inst->panEnvelope != NULL )
  716.                 {
  717.                     if ( (error = memFree(inst->panEnvelope)) != OK )
  718.                         PASSERROR(ID_gmpFreeModule)
  719.                 }
  720.  
  721.                 DEBUGprintf("inst[%i]->samples\n", i);
  722.                 /* If the instrument has samples, deallocate them: */
  723.                 for ( s = 0; s < inst->numSamples; s++ )
  724.                 {
  725.                     /* If the sample has a Sound Device sample handle, remove
  726.                        it from the Sound Device: */
  727.                     if ( inst->samples[s].sdHandle != 0 )
  728.                     {
  729.                         if ( (error = gmpSD->RemoveSample(
  730.                             inst->samples[s].sdHandle)) != OK )
  731.                             PASSERROR(ID_gmpFreeModule)
  732.                     }
  733.  
  734.                     /* If the sample sample data is available, deallocate
  735.                        it: */
  736.                     if ( inst->samples[s].sample != NULL )
  737.                     {
  738.                         if ( (error = memFree(inst->samples[s].sample)) != OK)
  739.                             PASSERROR(ID_gmpFreeModule)
  740.                     }
  741.                 }
  742.  
  743.                 DEBUGprintf("inst[%i]\n", i);
  744.                 /* Deallocate the instrument structure: */
  745.                 if ( (error = memFree(inst)) != OK )
  746.                     PASSERROR(ID_gmpFreeModule)
  747.             }
  748.  
  749.         }
  750.  
  751.         DEBUGputs("module->instruments");
  752.         /* Deallocate instrument structure pointers: */
  753.         if ( (error = memFree(module->instruments)) != OK )
  754.             PASSERROR(ID_gmpFreeModule)
  755.     }
  756.  
  757.     /* If the module has pattern data, deallocate it: */
  758.     if ( module->patterns != NULL )
  759.     {
  760.         for ( i = 0; i < module->numPatts; i++ )
  761.         {
  762.             DEBUGprintf("patterns[%i]\n", i);
  763.             /* If current pattern is allocated, deallocate it: */
  764.             if ( module->patterns[i] != NULL )
  765.             {
  766.                 if ( (error = memFree(module->patterns[i])) != OK )
  767.                     PASSERROR(ID_gmpFreeModule)
  768.             }
  769.         }
  770.  
  771.         DEBUGputs("module->patterns");
  772.         /* Deallocate pattern pointers: */
  773.         if ( (error = memFree(module->patterns)) != OK )
  774.             PASSERROR(ID_gmpFreeModule)
  775.     }
  776.  
  777.     DEBUGputs("module");
  778.     /* Deallocate the module structure: */
  779.     if ( (error = memFree(module)) != OK )
  780.         PASSERROR(ID_gmpFreeModule)
  781.  
  782.     return OK;
  783. }
  784.  
  785.  
  786.  
  787.  
  788. /****************************************************************************\
  789. *
  790. * Function:     int gmpPlay(void)
  791. *
  792. * Description:  Plays music for one song tick.
  793. *
  794. * Returns:      MIDAS error code.
  795. *
  796. \****************************************************************************/
  797.  
  798. int CALLING gmpPlay(void)
  799. {
  800.     int         error;
  801.     gmpPlayHandle handle;
  802.     unsigned    handleNum;
  803.  
  804.     /* Do for all playing handles: */
  805.     for ( handleNum = 0; handleNum < MAXSONGS; handleNum++ )
  806.     {
  807.         if ( playHandles[handleNum] != NULL )
  808.         {
  809.             /* Handle number is in use - play: */
  810.             handle = playHandles[handleNum];
  811.  
  812.             /* Increase handle tick counter: */
  813.             handle->playCount++;
  814.  
  815.             /* If playCount reached speed process new pattern data, otherwise
  816.                just handle continuous commands: */
  817.             if ( handle->playCount >= handle->speed )
  818.             {
  819.                 handle->playCount = 0;
  820.  
  821.                 if ( (error = gmpPlayPattern(handle)) != OK )
  822.                     PASSERROR(ID_gmpPlay)
  823.             }
  824.             else
  825.             {
  826.                 if ( (error = gmpHandleCommands(handle)) != OK )
  827.                     PASSERROR(ID_gmpPlay)
  828.             }
  829.  
  830.             if ( ( error = gmpRunEnvelopes(handle)) != OK )
  831.                     PASSERROR(ID_gmpPlay)
  832.         }
  833.     }
  834.  
  835.     return OK;
  836. }
  837.  
  838.  
  839.  
  840.  
  841. /****************************************************************************\
  842. *
  843. * Function:     int gmpGetInformation(gmpPlayHandle playHandle,
  844. *                   gmpInformation **information);
  845. *
  846. * Description:  Reads current playing status on a playing handle
  847. *
  848. * Input:        gmpPlayHandle playHandle        playing handle
  849. *               gmpInformation **information    pointer to pointer to
  850. *                                               information structure
  851. *
  852. * Returns:      MIDAS error code. Pointer to GMP information structure filled
  853. *               is written to *information.
  854. *
  855. \****************************************************************************/
  856.  
  857. int CALLING gmpGetInformation(gmpPlayHandle playHandle,
  858.     gmpInformation **information)
  859. {
  860.     /* Set information structure tempo and speed values: (pos, row and patt.
  861.        are updated in gmpPlay()) */
  862.     playHandle->information->speed = playHandle->speed;
  863.     playHandle->information->tempo = gmpTempo;
  864.  
  865.     playHandle->information->syncInfo = playHandle->syncInfo;
  866.  
  867.     /* Return information structure pointer in *information: */
  868.     *information = playHandle->information;
  869.  
  870.     return OK;
  871. }
  872.  
  873.  
  874.  
  875. /****************************************************************************\
  876. *
  877. * Function:     int gmpRunEnvelopes(gmpPlayHandle playHandle)
  878. *
  879. * Description:  Process envelopes for a playing handle
  880. *
  881. * Input:        gmpPlayHandle playHandle   playing handle
  882. *
  883. * Returns:      MIDAS error code
  884. *
  885. \****************************************************************************/
  886.  
  887. int gmpRunEnvelopes(gmpPlayHandle playHandle)
  888. {
  889.     int             error;
  890.     unsigned        chanNum;
  891.     int             x, y, tx, ty;
  892.     /* signed long     vol, pan; */
  893.     int             vol, pan;
  894.     int             i, point, val;
  895.     static ulong rate;
  896.     gmpInstrument   *inst;
  897.     gmpEnvelope     *env;
  898.  
  899.     /* Point gmpHandle to current playing handle: */
  900.     gmpHandle = playHandle;
  901.  
  902.     /* Point gmpCurModule to current playing module: */
  903.     gmpCurModule = gmpHandle->module;
  904.  
  905.     /* Set gmpPlayMode to current playing mode: */
  906.     gmpPlayMode = gmpCurModule->playMode;
  907.  
  908.     for ( chanNum = 0; chanNum < playHandle->numChannels; chanNum++ )
  909.     {
  910.         gmpChan = &playHandle->channels[chanNum];
  911.  
  912.         switch ( gmpPlayMode )
  913.         {
  914.             case gmpFT2:
  915.                 vol = gmpChan->realVolume;
  916.                 if ( gmpChan->instrument != -1 )
  917.                 {
  918.                     inst = gmpCurModule->instruments[gmpChan->instrument];
  919.  
  920.                     vol = (vol * gmpChan->fadeOut) >> 16;
  921.                     if ( gmpChan->keyOff != 0)
  922.                     {
  923.                         gmpChan->fadeOut -= 2*inst->volFadeout;
  924.                         if ( gmpChan->fadeOut < 0 ) gmpChan->fadeOut = 0;
  925.                     }
  926.  
  927.                     if ( ( env = inst->volEnvelope ) != NULL)
  928.                     {
  929.                         point = -1;
  930.  
  931.                         for ( i = 0; i < env->numPoints; i++ )
  932.                         {
  933.                             if ( gmpChan->volEnvX <= env->points[i * 2] )
  934.                             {
  935.                                 point = i;
  936.                                 break;
  937.                             }
  938.                         }
  939.                         if ( point == -1 )
  940.                             point = i - 1;
  941.  
  942.                         if ( gmpChan->volEnvX == env->points[point * 2] )
  943.                         {
  944.                             y = env->points[point * 2 + 1] * 256;
  945.                         }
  946.                         else
  947.                         {
  948.                             y = env->points[point * 2 - 1] ;
  949.                             ty = env->points[point * 2 + 1] - y;
  950.                             x = env->points[point * 2 - 2];
  951.                             tx = env->points[point * 2] - x;
  952.                             y *= 256;
  953.                             y += ty * 256 / tx * ( gmpChan->volEnvX - x );
  954.                         }
  955.                         vol = ( vol * y ) >> 14;
  956.                         if ( vol < 0 ) vol = 0;
  957.                         if ( vol > 64 ) vol = 64;
  958.  
  959.                         if ( ( gmpChan->volEnvX == env->points[env->sustain * 2]) &&
  960.                             (gmpChan->keyOff == 0) && ( env->sustain != -1 ) )
  961.                             gmpChan->volSustained = 1;
  962.  
  963.                         if ( !gmpChan->volSustained  )
  964.                         {
  965.                             if ( gmpChan->volEnvX < env->points[env->numPoints * 2 - 2] )
  966.                                 gmpChan->volEnvX++;
  967.  
  968.                             if ( (gmpChan->volEnvX >= env->points[env->loopEnd * 2] )&&
  969.                                  (env->loopEnd != -1 ) )
  970.                                 gmpChan->volEnvX = env->points[env->loopStart * 2];
  971.                             if ( ( gmpChan->volEnvX == env->points[env->sustain * 2]) &&
  972.                                 (gmpChan->keyOff == 0) && ( env->sustain != -1 ) )
  973.                                 gmpChan->volSustained = 1;
  974.                         }
  975.                     }
  976.                 }
  977.  
  978.                 vol = ( vol * playHandle->masterVolume ) >> 6;
  979.  
  980.                 if ( vol > 64 )
  981.                     vol = 64;
  982.                 if ( vol < 0 )
  983.                     vol = 0;
  984.  
  985.                 gmpChan->trueVolume = (uchar) vol;
  986.  
  987.                 if ( (error = gmpSD->SetVolume(gmpChan->sdChannel, vol)) != OK )
  988.                     PASSERROR(ID_gmpRunEnvelopes)
  989.  
  990.                 pan = gmpChan->panning;
  991. /*                DEBUGprintf("pan %i\n", (int) pan); */
  992.  
  993.                 if ( gmpChan->instrument != -1 )
  994.                 {
  995.                     inst = gmpCurModule->instruments[gmpChan->instrument];
  996.  
  997.                     if ( ( env = inst->panEnvelope ) != NULL)
  998.                     {
  999.                         point = -1;
  1000.  
  1001.                         for ( i = 0; i < env->numPoints; i++ )
  1002.                         {
  1003.                             if ( gmpChan->panEnvX <= env->points[i * 2] )
  1004.                             {
  1005.                                 point = i;
  1006.                                 break;
  1007.                             }
  1008.                         }
  1009.                         if ( point == -1 )
  1010.                             point = i;
  1011.  
  1012.                         if ( gmpChan->panEnvX == env->points[point * 2] )
  1013.                         {
  1014.                             y = env->points[point * 2 + 1] * 256;
  1015.                         }
  1016.                         else
  1017.                         {
  1018.                             y = env->points[point * 2 - 1];
  1019.                             ty = env->points[point * 2 + 1] - y;
  1020.                             x = env->points[point * 2 - 2];
  1021.                             tx = env->points[point * 2] - x;
  1022.                             y *= 256;
  1023.                             y += ty * 256 / tx * ( gmpChan->panEnvX - x );
  1024.                         }
  1025.  
  1026.  
  1027.                         /* Was
  1028.                             pan = pan + ( ( y >> 8 ) - 32 )
  1029.                                 * (128-abs(pan-128)) / 32;
  1030.                            Eliminated the need to use abs():
  1031.                         */
  1032.  
  1033.                         if ( pan >= 128 )
  1034.                         {
  1035.                             pan = pan + ( ( y >> 8 ) - 32 )
  1036.                                 * (128-(pan-128)) / 32;
  1037.                         }
  1038.                         else
  1039.                         {
  1040.                             pan = pan + ( ( y >> 8 ) - 32 )
  1041.                                 * (128+(pan-128)) / 32;
  1042.                         }
  1043.  
  1044.                         /* [Petteri] Was: if ( pan < 0 ) pan = 255; - feature? */
  1045.                         if ( pan < 0 ) pan = 0;
  1046.                         if ( pan > 255 ) pan = 255;
  1047.  
  1048.                         if ( ( gmpChan->panEnvX == env->points[env->sustain * 2]) &&
  1049.                             (gmpChan->keyOff == 0) && ( env->sustain != -1 ) )
  1050.                             gmpChan->panSustained = 1;
  1051.  
  1052.                         if ( !gmpChan->panSustained  )
  1053.                         {
  1054.                             if ( gmpChan->panEnvX < env->points[env->numPoints * 2 - 2] )
  1055.                                 gmpChan->panEnvX++;
  1056.  
  1057.                             if ( (gmpChan->panEnvX >= env->points[env->loopEnd * 2] ) &&
  1058.                                  (env->loopEnd != -1 ) )
  1059.                                 gmpChan->panEnvX = env->points[env->loopStart * 2];
  1060.                             if ( ( gmpChan->panEnvX == env->points[env->sustain * 2]) &&
  1061.                                 (gmpChan->keyOff == 0) && ( env->sustain != -1 ) )
  1062.                                 gmpChan->panSustained = 1;
  1063.                         }
  1064.  
  1065.                     }
  1066.                 }
  1067.  
  1068.                 pan = (pan - 0x80) / 2;
  1069.  
  1070.                 if ( pan < panLeft )
  1071.                     pan = panLeft;
  1072.                 if ( pan > panRight )
  1073.                     pan = panRight;
  1074.  
  1075.                 /* Set panning to Sound Device: */
  1076.                 if ( (error = gmpSD->SetPanning(gmpChan->sdChannel, pan)) != OK )
  1077.                     PASSERROR(ID_gmpRunEnvelopes)
  1078.  
  1079.  
  1080.                 /* Run autovibrato */
  1081.  
  1082.                 if ( gmpChan->instrument != -1 )
  1083.                 {
  1084.                     inst = gmpCurModule->instruments[gmpChan->instrument];
  1085.  
  1086.                     if ( inst->vibDepth == 0)
  1087.                     {
  1088.                         /* no vibrato... */
  1089.                         gmpChan->truePeriod = gmpChan->realPeriod;
  1090.                     }
  1091.                     else
  1092.                     {
  1093.                         if ( inst->vibSweep == 0)
  1094.                             gmpChan->autoVibDepth = inst->vibDepth << 8;
  1095.                         else
  1096.                         {
  1097.                             if ( !gmpChan->keyOff )
  1098.                             {
  1099.                                 gmpChan->autoVibDepth +=
  1100.                                     ( inst->vibDepth << 8 ) / inst->vibSweep;
  1101.                                 if ( (gmpChan->autoVibDepth >> 8 ) > inst->vibDepth )
  1102.                                     gmpChan->autoVibDepth = inst->vibDepth << 8;
  1103.                             }
  1104.                         }
  1105.  
  1106.                         gmpChan->autoVibPos += inst->vibRate;
  1107.  
  1108.                         switch (inst->vibType)
  1109.                         {
  1110.                             case 3:
  1111.                                 val = ((0x40-(gmpChan->autoVibPos>>1))&0x7f)-0x40;
  1112.                                 break;
  1113.                             case 2:
  1114.                                 val = ((0x40+(gmpChan->autoVibPos>>1))&0x7f)-0x40;
  1115.                                 break;
  1116.                             case 1:
  1117.                                 val = gmpChan->autoVibPos & 128 ? +64 : -64;
  1118.                                 break;
  1119.                             case 0:
  1120.                             default:
  1121.                                 val = ft2VibratoTable[gmpChan->autoVibPos & 255];
  1122.                                 break;
  1123.                         }
  1124.  
  1125.                         gmpChan->truePeriod = gmpChan->realPeriod +
  1126.                             ((val * gmpChan->autoVibDepth ) >> 14);
  1127.  
  1128.                         /* Limit period value within current limits: */
  1129.                         if ( gmpChan->truePeriod <
  1130.                                 (int) gmpHandle->perLimitLow )
  1131.                             gmpChan->truePeriod = gmpHandle->perLimitLow;
  1132.                         if ( gmpChan->truePeriod >
  1133.                                 (int) gmpHandle->perLimitUp )
  1134.                             gmpChan->truePeriod = gmpHandle->perLimitUp;
  1135.                     }
  1136.  
  1137.                     if ( gmpChan->truePeriod != 0 )
  1138.                     {
  1139.                         /* Get rate corresponding to period value: */
  1140.                         if ( (error = gmpPeriodRate(gmpChan->truePeriod,
  1141.                             &rate)) != OK )
  1142.                             PASSERROR(ID_gmpSetPeriod)
  1143.  
  1144.                         /* Set new playing rate to Sound Device: */
  1145.                         if ( (error = gmpSD->SetRate(gmpChan->sdChannel,
  1146.                             rate)) != OK )
  1147.                             PASSERROR(ID_gmpSetPeriod)
  1148.                     }
  1149.                 }
  1150.                 break;
  1151.  
  1152.             default:
  1153.                 vol = ( gmpChan->realVolume * playHandle->masterVolume ) >> 6;
  1154.                 gmpChan->trueVolume = (uchar) vol;
  1155.  
  1156.                 /* Set volume to Sound Device: */
  1157.                 if ( (error = gmpSD->SetVolume(gmpChan->sdChannel, vol)) != OK )
  1158.                     PASSERROR(ID_gmpRunEnvelopes)
  1159.  
  1160.                 gmpChan->truePeriod = gmpChan->realPeriod;
  1161.  
  1162.                 /* If a period has been set, set it to Sound Device: */
  1163.                 if ( gmpChan->truePeriod != 0 )
  1164.                 {
  1165.                     /* Get rate corresponding to period value: */
  1166.                     if ( (error = gmpPeriodRate(gmpChan->truePeriod, &rate))
  1167.                         != OK )
  1168.                         PASSERROR(ID_gmpSetPeriod)
  1169.  
  1170.                     /* Set new playing rate to Sound Device: */
  1171.                     if ( (error = gmpSD->SetRate(gmpChan->sdChannel, rate))
  1172.                         != OK )
  1173.                         PASSERROR(ID_gmpSetPeriod)
  1174.                 }
  1175.                 break;
  1176.         }
  1177.     }
  1178.     return  OK;
  1179. }
  1180.  
  1181. /****************************************************************************\
  1182. *
  1183. * Function:     int gmpPlayPattern(gmpPlayHandle playHandle)
  1184. *
  1185. * Description:  Process one row of new pattern data for a playing handle
  1186. *
  1187. * Input:        gmpPlayHandle playHandle   playing handle
  1188. *
  1189. * Returns:      MIDAS error code
  1190. *
  1191. \****************************************************************************/
  1192.  
  1193. int gmpPlayPattern(gmpPlayHandle playHandle)
  1194. {
  1195.     unsigned    chanNum;
  1196.     int         error, row, xmNote;
  1197.     uchar       compInfo;
  1198.     uchar       note, inst;
  1199.     uchar       *pattData;
  1200.     uchar       command, infobyte;
  1201.     gmpInstrument *instStruct;
  1202.     int (**Commands)(unsigned);         /* pointer to command table */
  1203.  
  1204.     /* Point pattData to current pattern playing position: */
  1205.     pattData = playHandle->playPtr;
  1206.  
  1207.     /* Point gmpHandle to current playing handle: */
  1208.     gmpHandle = playHandle;
  1209.  
  1210.     /* Point gmpCurModule to current playing module: */
  1211.     gmpCurModule = gmpHandle->module;
  1212.  
  1213.     /* Set gmpPlayMode to current playing mode: */
  1214.     gmpPlayMode = gmpCurModule->playMode;
  1215.  
  1216.     /* Set Commands to point to appropriate command pointer table: */
  1217.     switch ( gmpPlayMode )
  1218.     {
  1219.         case gmpPT:
  1220.         default:
  1221.             Commands = &gmpTick0CommandsPT[0];
  1222.             break;
  1223.  
  1224.         case gmpFT2:
  1225.             Commands = &gmpTick0CommandsFT2[0];
  1226.             break;
  1227.  
  1228.         case gmpST3:
  1229.             Commands = &gmpTick0CommandsST3[0];
  1230.             break;
  1231.     }
  1232.  
  1233.     /* Set playing handle information structure position, pattern and row
  1234.        fields now so that they reflect the current playing values, not the
  1235.        next ones: */
  1236.     gmpHandle->information->position = gmpHandle->position;
  1237.     gmpHandle->information->pattern = gmpHandle->pattern;
  1238.     gmpHandle->information->row = gmpHandle->row;
  1239.  
  1240.     /* If pattern delay is in progress, run both tick 0 and continuous
  1241.        commands, decrease delay counter and exit: */
  1242.     if ( gmpHandle->pattDelayCount )
  1243.     {
  1244.         /* Run tick 0 commands: */
  1245.         gmpChan = &gmpHandle->channels[0];
  1246.         for ( chanNum = 0; chanNum < gmpHandle->numChannels; chanNum++ )
  1247.         {
  1248.             /* Run command for this channel if there is one: */
  1249.             if ( gmpChan->status.command )
  1250.             {
  1251.                 if ( (error = Commands[gmpChan->command](gmpChan->infobyte))
  1252.                     != OK )
  1253.                     PASSERROR(ID_gmpPlayPattern)
  1254.             }
  1255.             gmpChan++;
  1256.         }
  1257.  
  1258.         /* Run continuous commands: */
  1259.         if ( (error = gmpHandleCommands(gmpHandle)) != OK )
  1260.             PASSERROR(ID_gmpPlayPattern)
  1261.  
  1262.         /* Decrease pattern delay counter: */
  1263.         gmpHandle->pattDelayCount--;
  1264.  
  1265.         return OK;
  1266.     }
  1267.  
  1268.     /* If pattData is NULL, playing position has been changed and new position
  1269.        must be set: */
  1270.     if ( pattData == NULL )
  1271.     {
  1272.         /* Get the start address of current pattern: */
  1273.         pattData = (uchar*) gmpCurModule->patterns[playHandle->pattern]
  1274.             + sizeof(gmpPattern);
  1275.  
  1276.         /* Skip pattern data to correct row number: */
  1277.         row = gmpHandle->row;
  1278.         while ( row )
  1279.         {
  1280.             do
  1281.             {
  1282.                 /* Get compression infobyte: */
  1283.                 compInfo = *(pattData++);
  1284.  
  1285.                 /* Skip all data bytes required: */
  1286.                 if ( compInfo & 32 )
  1287.                     pattData += 2;
  1288.                 if ( compInfo & 64 )
  1289.                     pattData += 1;
  1290.                 if ( compInfo & 128 )
  1291.                     pattData += 2;
  1292.             } while ( compInfo != 0 );
  1293.  
  1294.             row--;
  1295.         }
  1296.     }
  1297.  
  1298.     /* Clear all new data flags from all channels: */
  1299.     for ( chanNum = 0; chanNum < playHandle->numChannels; chanNum++ )
  1300.     {
  1301.         playHandle->channels[chanNum].status.newNote = 0;
  1302.         playHandle->channels[chanNum].status.newInst = 0;
  1303.         playHandle->channels[chanNum].status.newVolume = 0;
  1304.         playHandle->channels[chanNum].status.command = 0;
  1305.     }
  1306.  
  1307.     /* Parse new pattern data: */
  1308.     do
  1309.     {
  1310.         /* Get compression information byte: */
  1311.         compInfo = *(pattData++);
  1312.  
  1313.         /* Get channel number: */
  1314.         chanNum = compInfo & 31;
  1315.  
  1316.         /* If channel data should not be played, skip it: */
  1317.         if ( chanNum >= playHandle->numChannels )
  1318.         {
  1319.             if ( compInfo & 32 )
  1320.                 pattData += 2;
  1321.             if ( compInfo & 64 )
  1322.                 pattData += 1;
  1323.             if ( compInfo & 128 )
  1324.                 pattData += 2;
  1325.         }
  1326.         else
  1327.         {
  1328.             /* Point chan to current channel: */
  1329.             gmpChan = &playHandle->channels[chanNum];
  1330.  
  1331.             /* Check if there is a new note+instrument pair: */
  1332.             if ( compInfo & 32 )
  1333.             {
  1334.                 /* Get note: */
  1335.                 note = *(pattData++);
  1336.  
  1337.                 /* Get instrument: */
  1338.                 inst = *(pattData++);
  1339.  
  1340.                 /* If note number is not 0xFF, there is a new note: */
  1341.                 if ( note != 0xFF )
  1342.                 {
  1343.                     gmpChan->status.newNote = 1;
  1344.                     gmpChan->note = note;
  1345.                 }
  1346.  
  1347.                 /* If instrument number is not 0xFF, there is a new
  1348.                    instrument: */
  1349.                 if ( inst != 0xFF )
  1350.                 {
  1351.                     gmpChan->status.newInst = 1;
  1352.                     gmpChan->newInstrument = inst;
  1353.                 }
  1354.             }
  1355.  
  1356.             /* Check if there is a volume column value: */
  1357.             if ( compInfo & 64 )
  1358.             {
  1359.                 gmpChan->volColumn = *(pattData++);
  1360.                 gmpChan->status.newVolume = 1;
  1361.             }
  1362.  
  1363.             /* Check if there is a command+infobyte pair: */
  1364.             if ( compInfo & 128 )
  1365.             {
  1366.                 gmpChan->command = *(pattData++);
  1367.                 gmpChan->infobyte = *(pattData++);
  1368.                 gmpChan->status.command = 1;
  1369.             }
  1370.         }
  1371.     } while ( compInfo != 0 );
  1372.  
  1373.  
  1374.     /* Store new pattern data playing position: */
  1375.     gmpHandle->playPtr = pattData;
  1376.  
  1377.     /* Now process new data on all channels: */
  1378.     gmpChan = &playHandle->channels[0];
  1379.     for ( chanNum = 0; chanNum < playHandle->numChannels; chanNum++ )
  1380.     {
  1381.         /* Check if there is a new instrument for this channel: */
  1382.         /* FIXME - note delay on ST3 and FT2 */
  1383.  
  1384.         if ( gmpChan->status.newInst )
  1385.         {
  1386.             switch ( gmpPlayMode )
  1387.             {
  1388.                 case gmpPT :
  1389.                 case gmpST3 :
  1390.                     gmpChan->instrument = gmpChan->newInstrument;
  1391.  
  1392.                     /* Point instStruct to new instrument: */
  1393.                     instStruct = gmpCurModule->instruments[gmpChan->instrument];
  1394.  
  1395.                     /* Set instrument volume as current channel volume: */
  1396.                     gmpSetVolume(instStruct->samples[0].volume);
  1397.  
  1398.                     /* Set channel sample number as zero: */
  1399.                     gmpChan->sample = 0;
  1400.  
  1401.                     /* Set new note start offset to zero: */
  1402.                     gmpChan->startOffset = 0;
  1403.  
  1404.                     /* Set the sample to the Sound Device: */
  1405.                     if ( (error = gmpSD->SetSample(gmpChan->sdChannel,
  1406.                         instStruct->samples[0].sdHandle)) != OK )
  1407.                         PASSERROR(ID_gmpPlayPattern)
  1408.                     break;
  1409.  
  1410.                 case gmpFT2:
  1411.                     gmpChan->volEnvX = 0;
  1412.                     gmpChan->volSustained = 0;
  1413.                     gmpChan->panEnvX = 0;
  1414.                     gmpChan->panSustained = 0;
  1415.                     gmpChan->fadeOut = 0x10000;
  1416.                     gmpChan->autoVibPos = 0;
  1417.                     gmpChan->autoVibDepth = 0;
  1418.  
  1419.                     /* Key is not released any more: */
  1420.                     gmpChan->keyOff = 0;
  1421.  
  1422.                     /* We'll only actually change the instrument if there is
  1423.                        a new note: */
  1424.                     if ( (gmpChan->status.newNote) && (gmpChan->note < 0xFE)
  1425.                         && ((!gmpChan->status.command) ||
  1426.                             (gmpChan->command != gmpcTonePortamento)) )
  1427.                     {
  1428.                         gmpChan->instrument = gmpChan->newInstrument;
  1429.                         instStruct = gmpCurModule->instruments[
  1430.                             gmpChan->instrument];
  1431.  
  1432.                         xmNote = gmpChan->note;
  1433.                         if ( xmNote < 0xFE )
  1434.                         {
  1435.                             xmNote = (xmNote & 0xF) + (((xmNote & 0xF0) >> 4) * 12);
  1436.                             if ( xmNote > 95 ) xmNote = 95;
  1437.                             if ( xmNote < 0 ) xmNote = 0;
  1438.  
  1439.                             /* Set channel sample number: */
  1440.                             if ( instStruct->noteSamples != NULL )
  1441.                                 gmpChan->sample =
  1442.                                     instStruct->noteSamples[xmNote];
  1443.                             else
  1444.                                 gmpChan->sample = 0;
  1445.                         }
  1446.                     }
  1447.  
  1448.                     /* Point instStruct to new instrument: */
  1449.                     instStruct = gmpCurModule->instruments[gmpChan->instrument];
  1450.  
  1451.                     if ( gmpChan->sample != 0xff )
  1452.                     {
  1453.                         /* Set instrument volume as current channel volume: */
  1454.                         gmpSetVolume(instStruct->samples[gmpChan->sample].volume);
  1455.  
  1456.                         /* Set instrument panning as current channel panning: */
  1457.                         gmpSetPanning(instStruct->samples[gmpChan->sample].panning);
  1458.  
  1459.                         /* Set new note start offset to zero: */
  1460.                         gmpChan->startOffset = 0;
  1461.  
  1462.                         if ( gmpChan->status.newNote )
  1463.                         {
  1464.                             /* Set the sample to the Sound Device: */
  1465.                             if ( instStruct->samples[gmpChan->sample].sdHandle != 0 )
  1466.                                 if ( (error = gmpSD->SetSample(gmpChan->sdChannel,
  1467.                                     instStruct->samples[gmpChan->sample].sdHandle)) != OK )
  1468.                                     PASSERROR(ID_gmpPlayPattern)
  1469.                         }
  1470.                     }
  1471.  
  1472.                     break;
  1473.             }
  1474.         }
  1475.  
  1476.         /* Check if there is a new volume column value: */
  1477.         if ( gmpChan->status.newVolume )
  1478.         {
  1479.             /* Check if it is a volume change: */
  1480.             if (gmpChan->volColumn <= 64 )
  1481.             {
  1482.                 if ( (error = gmpSetVolume(gmpChan->volColumn)) != OK )
  1483.                     PASSERROR(ID_gmpPlayPattern)
  1484.             }
  1485.             else
  1486.             {
  1487.                 /* Volume column command: */
  1488.                 if ( (error = gmpSetVolCommand()) != OK )
  1489.                     PASSERROR(ID_gmpPlayPattern)
  1490.             }
  1491.         }
  1492.  
  1493.         /* Check if there is a command for this channel: */
  1494.         if ( gmpChan->status.command )
  1495.         {
  1496.             if ( gmpChan->command != gmpcNone )
  1497.             {
  1498.                 command = gmpChan->command;
  1499.                 infobyte = gmpChan->infobyte;
  1500.  
  1501.                 /* Check that the command number is legal: */
  1502.                 if ( command >= gmpNumCommands )
  1503.                 {
  1504.                     ERROR(errInvalidPatt, ID_gmpPlayPattern);
  1505.                     return errInvalidPatt;
  1506.                 }
  1507.  
  1508.                 /* If the infobyte is nonzero, we'll save it as the
  1509.                    "old infobyte": */
  1510.                 if ( infobyte != 0  )
  1511.                 {
  1512.                     switch ( gmpPlayMode )
  1513.                     {
  1514.                         case gmpST3:
  1515.                             gmpChan->oldInfo = infobyte;
  1516.                             break;
  1517.  
  1518.                         case gmpFT2:
  1519.                             gmpChan->oldInfobytes[command] = infobyte;
  1520.                             break;
  1521.                     }
  1522.                 }
  1523.                 else
  1524.                 {
  1525.                     /* The infobyte is 0 - use "old infobyte" if necessary: */
  1526.                     switch ( gmpPlayMode )
  1527.                     {
  1528.                         case gmpST3:
  1529.                             infobyte = gmpChan->oldInfo;
  1530.                             break;
  1531.  
  1532.                         case gmpFT2:
  1533.                             if ( ft2UsePrevInfo[command] )
  1534.                                 infobyte = gmpChan->oldInfobytes[command];
  1535.                             break;
  1536.                     }
  1537.                 }
  1538.  
  1539. /*                DEBUGprintf("Tick-0 command %i\n", gmpChan->command); */
  1540.  
  1541.                 /* Handle the command - call the appropriate tick 0 command
  1542.                    routine: */
  1543.                 if ( (error = Commands[command](infobyte)) != OK )
  1544.                     PASSERROR(ID_gmpPlayPattern)
  1545.             }
  1546.         }
  1547.  
  1548.         /* Check if there is a new note: */
  1549.         if ( gmpChan->status.newNote )
  1550.         {
  1551.             if ( (gmpPlayMode == gmpFT2) && (gmpChan->instrument != -1) )
  1552.             {
  1553.                 /* Point instStruct to new instrument: */
  1554.                 instStruct = gmpCurModule->instruments[gmpChan->instrument];
  1555.  
  1556.                 xmNote = gmpChan->note;
  1557.                 if ( xmNote < 0xFE )
  1558.                 {
  1559.                     xmNote = (xmNote & 0xF) + (((xmNote & 0xF0) >> 4) * 12);
  1560.                     if ( xmNote > 95 ) xmNote = 95;
  1561.                     if ( xmNote < 0 ) xmNote = 0;
  1562.  
  1563.                     /* Set channel sample number: */
  1564.                     if ( instStruct->noteSamples != NULL )
  1565.                         gmpChan->sample = instStruct->noteSamples[xmNote];
  1566.                     else
  1567.                         gmpChan->sample = 0;
  1568.                 }
  1569.  
  1570.                 if ( ( gmpChan->sample != 0xff ) && ( gmpChan->note != 0xFE ) )
  1571.                 {
  1572.                     /* Set new note start offset to zero: */
  1573.                     gmpChan->startOffset = 0;
  1574.  
  1575.                     gmpChan->instrument = gmpChan->newInstrument;
  1576.                     /* Point instStruct to new instrument: */
  1577.                     instStruct = gmpCurModule->instruments[gmpChan->instrument];
  1578.  
  1579.                     /* Set the sample to the Sound Device: */
  1580.                     if ( instStruct->samples[gmpChan->sample].sdHandle != 0 )
  1581.                         if ( (error = gmpSD->SetSample(gmpChan->sdChannel,
  1582.                             instStruct->samples[gmpChan->sample].sdHandle)) != OK )
  1583.                             PASSERROR(ID_gmpPlayPattern)
  1584.                 }
  1585.             }
  1586.             /* Play the note: */
  1587.             if ( (error = gmpNewNote()) != OK )
  1588.                 PASSERROR(ID_gmpPlayPattern)
  1589.         }
  1590.         else
  1591.         {
  1592.             /* Always reset channel period when there is no new note unless
  1593.                there is a vibrato command active (except for Protracker mode
  1594.                where the period is always resetted): */
  1595.             if ( (gmpPlayMode == gmpPT) || (gmpPlayMode == gmpST3) ||
  1596.                 (((gmpChan->command != gmpcVibrato) ||
  1597.                 (!gmpChan->status.command)) && ((gmpChan->volColumn & 0xF0)
  1598.                 != 0xB0)) )
  1599.             {
  1600.                 /* Reset channel period: */
  1601.                 if ( (error = gmpChangePeriod(gmpChan->period)) != OK )
  1602.                     PASSERROR(ID_gmpPlayPattern)
  1603.             }
  1604.         }
  1605.  
  1606.         /* Point gmpChan to next channel: */
  1607.         gmpChan++;
  1608.     }
  1609.  
  1610.     /* Continue from next row if playing position has not been changed: */
  1611.     if ( gmpHandle->playPtr != NULL )
  1612.     {
  1613.         gmpHandle->row++;
  1614.  
  1615.         /* Check if we reached pattern end: */
  1616.         if ( gmpHandle->row >=
  1617.             gmpCurModule->patterns[gmpHandle->pattern]->rows )
  1618.         {
  1619.             gmpHandle->row = 0;
  1620.  
  1621.             /* Reset pattern loop destination row if playing ST3 module: */
  1622.             if ( gmpPlayMode == gmpST3 )
  1623.                 gmpHandle->loopRow = 0;
  1624.  
  1625.             /* Go to next position skipping S3M song data filler: */
  1626.             do
  1627.             {
  1628.                 gmpHandle->position++;
  1629.  
  1630.                 /* Check if we reached song length, and if so, jump to restart
  1631.                    position: */
  1632.                 if ( (gmpHandle->position > gmpHandle->songEnd) ||
  1633.                     (gmpCurModule->songData[gmpHandle->position] == 0xffff))
  1634.                 {
  1635.                     gmpHandle->position = gmpHandle->restartPos;
  1636.                 }
  1637.             } while ( gmpCurModule->songData[gmpHandle->position] == 0xfffe );
  1638.  
  1639.             /* Get the pattern number for new position: */
  1640.             gmpHandle->pattern = gmpCurModule->songData[gmpHandle->position];
  1641.  
  1642.             /* Set pattern data pointer to NULL to mark playing position
  1643.                has changed: */
  1644.             gmpHandle->playPtr = NULL;
  1645.         }
  1646.     }
  1647.  
  1648.     return OK;
  1649. }
  1650.  
  1651.  
  1652.  
  1653.  
  1654. /****************************************************************************\
  1655. *
  1656. * Function:     int gmpHandleCommands(gmpPlayHandle playHandle)
  1657. *
  1658. * Description:  Handle continuous commands for a playing handle
  1659. *
  1660. * Input:        gmpPlayHandle playHandle   playing handle
  1661. *
  1662. * Returns:      MIDAS error code
  1663. *
  1664. \****************************************************************************/
  1665.  
  1666. int gmpHandleCommands(gmpPlayHandle playHandle)
  1667. {
  1668.     unsigned    chanNum;
  1669.     int         error;
  1670.     unsigned    command, infobyte;
  1671.     int (**Commands)(unsigned);         /* pointer to command table */
  1672.  
  1673.     /* Point gmpHandle to current playing handle: */
  1674.     gmpHandle = playHandle;
  1675.  
  1676.     /* Point gmpCurModule to current playing module: */
  1677.     gmpCurModule = gmpHandle->module;
  1678.  
  1679.     /* Set gmpPlayMode to current playing mode: */
  1680.     gmpPlayMode = gmpCurModule->playMode;
  1681.  
  1682.     /* Set Commands to point to appropriate continuous command pointer
  1683.        table: */
  1684.     switch ( gmpPlayMode )
  1685.     {
  1686.         case gmpPT :
  1687.         default:
  1688.             Commands = &gmpContCommandsPT[0];
  1689.             break;
  1690.  
  1691.         case gmpFT2 :
  1692.             Commands = &gmpContCommandsFT2[0];
  1693.             break;
  1694.  
  1695.         case gmpST3 :
  1696.             Commands = &gmpContCommandsST3[0];
  1697.             break;
  1698.     }
  1699.  
  1700.     /* Handle commands on all channels: */
  1701.     gmpChan = &gmpHandle->channels[0];
  1702.     for ( chanNum = 0; chanNum < gmpHandle->numChannels; chanNum++ )
  1703.     {
  1704.         /* Check if there is a new volume column value: */
  1705.         if ( gmpChan->status.newVolume )
  1706.         {
  1707.             /* Check that it is a command: */
  1708.             if ( ( gmpChan->volColumn > 64 ) && ( gmpPlayMode == gmpFT2 ) )
  1709.             {
  1710.                 /* Volume column command: */
  1711.                 if ( (error = gmpRunVolCommand()) != OK )
  1712.                     PASSERROR(ID_gmpHandleCommands)
  1713.             }
  1714.         }
  1715.  
  1716.         /* Check if there is a command, and if is, handle it by calling the
  1717.            correct continuous command processing routine: */
  1718.         if ( gmpChan->status.command )
  1719.         {
  1720.             command = gmpChan->command;
  1721.             infobyte = gmpChan->infobyte;
  1722.  
  1723.             /* Check that the command number is legal: */
  1724.             if ( command >= gmpNumCommands )
  1725.             {
  1726.                 ERROR(errInvalidPatt, ID_gmpHandleCommands);
  1727.                 return errInvalidPatt;
  1728.             }
  1729.  
  1730.             /* Check if we should use the "old infobyte": */
  1731.             if ( infobyte == 0 )
  1732.             {
  1733.                 /* The infobyte is 0 - use "old infobyte" if necessary: */
  1734.                 switch ( gmpPlayMode )
  1735.                 {
  1736.                     case gmpST3:
  1737.                         infobyte = gmpChan->oldInfo;
  1738.                         break;
  1739.  
  1740.                     case gmpFT2:
  1741.                         if ( ft2UsePrevInfo[command] )
  1742.                             infobyte = gmpChan->oldInfobytes[command];
  1743.                         break;
  1744.                 }
  1745.             }
  1746.  
  1747. /*            DEBUGprintf("Continuous command %i\n", gmpChan->command); */
  1748.             if ( (error = Commands[command](infobyte)) != OK )
  1749.                 PASSERROR(ID_gmpHandleCommands)
  1750.         }
  1751.  
  1752.         /* Point gmpChan to next channel: */
  1753.         gmpChan++;
  1754.     }
  1755.  
  1756.     return OK;
  1757. }
  1758.  
  1759.  
  1760.  
  1761.  
  1762. /****************************************************************************\
  1763. *
  1764. * Function:     int gmpSetTempo(unsigned tempo)
  1765. *
  1766. * Description:  Changes current playing tempo. GMP internal use only. Updates
  1767. *               Sound Device and UpdRateFunct() update rates as necessary.
  1768. *
  1769. * Input:        unsigned tempo          new tempo in beats per minute
  1770. *
  1771. * Returns:      MIDAS error code.
  1772. *
  1773. \****************************************************************************/
  1774.  
  1775. int gmpSetTempo(unsigned tempo)
  1776. {
  1777.     int         error;
  1778.  
  1779.     /* Do a small sanity-check: */
  1780.     if ( tempo == 0 )
  1781.         return OK;
  1782.  
  1783.     /* Remember new tempo: */
  1784.     gmpTempo = tempo;
  1785.  
  1786.     /* Change Sound Device updating rate: */
  1787.     if ( (error = gmpSD->SetUpdRate(40*tempo)) != OK )
  1788.         PASSERROR(ID_gmpSetTempo)
  1789.  
  1790.     /* If update rate changing function has been set, call it: */
  1791.     if ( SetUpdRate != NULL )
  1792.     {
  1793.         if ( (error = SetUpdRate(40*tempo)) != OK )
  1794.             PASSERROR(ID_gmpSetTempo)
  1795.     }
  1796.  
  1797.     return OK;
  1798. }
  1799.  
  1800.  
  1801.  
  1802.  
  1803. /****************************************************************************\
  1804. *
  1805. * Function:     int gmpNotePeriod(unsigned note, unsigned *period)
  1806. *
  1807. * Description:  Converts a note number to a period value (both depend on
  1808. *               current playing mode). Uses *gmpChan and *gmpCurModule to
  1809. *               get sample tuning values. GMP internal.
  1810. *
  1811. * Input:        unsigned note           note number
  1812. *               unsigned *period        pointer to period value
  1813. *
  1814. * Returns:      MIDAS error code
  1815. *
  1816. \****************************************************************************/
  1817.  
  1818. int gmpNotePeriod(unsigned note, unsigned *period)
  1819. {
  1820.     int         finetune;
  1821.     int         realNote;
  1822.     gmpSample   *sample;
  1823.     int         rnote, roct, rfine;
  1824.     int         per1, per2;
  1825.  
  1826.     switch ( gmpPlayMode )
  1827.     {
  1828.         case gmpPT:
  1829.             /* Protracker playing mode: */
  1830.  
  1831.             /* Get finetune value from correct sample: */
  1832.             finetune = gmpCurModule->instruments[gmpChan->instrument]->
  1833.                 samples[gmpChan->sample].finetune;
  1834.  
  1835.             /* Get period value from correct part of period table for this
  1836.                finetune value and shift it right by the octave number: */
  1837.             *period = gmpPeriodsPT[12*finetune + (note & 0x0F)] >>
  1838.                 (note >> 4);
  1839.             break;
  1840.  
  1841.  
  1842.         case gmpFT2:
  1843.             /* Fasttracker 2 playing mode: */
  1844.  
  1845.             /* Point sample to current playing sample: */
  1846.             sample = &gmpCurModule->instruments[gmpChan->instrument]->
  1847.                 samples[gmpChan->sample];
  1848.  
  1849.             /* Calculate real note number: */
  1850.  
  1851.             realNote = (note & 15) + (((note & 0xf0) >> 4) * 12);
  1852.             realNote += sample->baseTune;
  1853.             if ( realNote > 118 )
  1854.                 realNote = 118;
  1855.             if ( realNote < 0 )
  1856.                 realNote = 0;
  1857.  
  1858. /*            DEBUGprintf("Noteperiod channel %i\n", gmpChan->sdChannel); */
  1859.  
  1860.             /* Check if we are using linear frequencies: */
  1861.             if ( gmpCurModule->playFlags.linFreqTable )
  1862.             {
  1863.                 *period = 10*12*16*4 - 16*4*realNote - sample->finetune / 2;
  1864. //                Period = 10*12*16*4 - Note*16*4 - FineTune/2;
  1865.             }
  1866.             else
  1867.             {
  1868.                 realNote = (realNote % 12) | ((realNote / 12) << 4);
  1869.                 finetune = sample->finetune;
  1870.  
  1871.                 /* Calculate period value for this note: */
  1872.  
  1873.                 rnote = realNote & 0xF;
  1874.                 roct = (realNote & 0xF0) >> 4;
  1875.                 rfine = finetune / 16;
  1876.  
  1877.                 rnote = rnote << 3;
  1878.                 per1 = gmpPeriodsFT2[rnote+rfine+8];
  1879.  
  1880.                 if ( finetune < 0 )
  1881.                 {
  1882.                     rfine--;
  1883.                     finetune = -finetune;
  1884.                 }
  1885.                 else
  1886.                     rfine++;
  1887.  
  1888.                 per2 = gmpPeriodsFT2[rnote+rfine+8];
  1889.  
  1890.                 rfine = finetune & 0xF;
  1891.                 per1 *= 16-rfine;
  1892.                 per2 *= rfine;
  1893.                 *period = ((per1 + per2) * 2) >> roct;
  1894.             }
  1895.             break;
  1896.  
  1897.         case gmpST3:
  1898.             /* Screamtracker 3 playing mode: */
  1899.  
  1900.             /* Point sample to current playing sample: */
  1901.             sample = &gmpCurModule->instruments[gmpChan->instrument]->
  1902.                 samples[gmpChan->sample];
  1903.  
  1904. /*
  1905.      Calculate sampling rate that corresponds to new note. A crazy
  1906.      method, but this is what the Scream Tracker 3 documentation
  1907.      says:
  1908.  
  1909.                      8363 * 16 * ( period(NOTE) >> octave(NOTE) )
  1910.     note_st3period = --------------------------------------------
  1911.                         middle_c_finetunevalue(INSTRUMENT)
  1912.  
  1913.     note_amigaperiod = note_st3period / 4
  1914.  
  1915.     note_herz=14317056 / note_st3period
  1916.  
  1917. */
  1918.             /* Calculate period value for this note: */
  1919.  
  1920.             *period = ( ( 8363 * 16 * ( gmpPeriodsST3[note & 0xF] ) )
  1921.                  >> ((note & 0xf0) >> 4) ) / sample->baseTune;
  1922.             break;
  1923.  
  1924.     }
  1925.  
  1926.     return OK;
  1927. }
  1928.  
  1929.  
  1930.  
  1931.  
  1932. /****************************************************************************\
  1933. *
  1934. * Function:     int gmpPlayNote(unsigned period)
  1935. *
  1936. * Description:  Starts playing a new note on channel *gmpChan with period
  1937. *               value period. GMP internal.
  1938. *
  1939. * Input:        unsigned period         period value for new note
  1940. *
  1941. * Returns:      MIDAS error code
  1942. *
  1943. \****************************************************************************/
  1944.  
  1945. int gmpPlayNote(unsigned period)
  1946. {
  1947.     static ulong rate;
  1948.     int         error;
  1949.  
  1950.     gmpChan->realPeriod = period;
  1951.  
  1952.     /* Get sampling rate corresponding to the new period value: */
  1953.     if ( (error = gmpPeriodRate(period, &rate)) != OK )
  1954.         PASSERROR(ID_gmpPlayNote)
  1955.  
  1956.     /* Start the note: */
  1957.     if ( (error = gmpSD->PlaySound(gmpChan->sdChannel, rate)) != OK )
  1958.         PASSERROR(ID_gmpPlayNote)
  1959.  
  1960.     return OK;
  1961. }
  1962.  
  1963.  
  1964.  
  1965.  
  1966. /****************************************************************************\
  1967. *
  1968. * Function:     int gmpPeriodRate(unsigned period, ulong *rate)
  1969. *
  1970. * Description:  Converts a period value to sampling rate, depending on current
  1971. *               playing mode. GMP internal.
  1972. *
  1973. * Input:        unsigned period         period number
  1974. *               ulong *rate             pointer to sampling rate
  1975. *
  1976. * Returns:      MIDAS error code.
  1977. *
  1978. \****************************************************************************/
  1979.  
  1980. int gmpPeriodRate(unsigned period, ulong *rate)
  1981. {
  1982.     /* FIXME */
  1983.  
  1984.     /* Check that the period value is nonzero: */
  1985.     if ( period == 0 )
  1986.     {
  1987.         ERROR(errInvalidPatt, ID_gmpPeriodRate);
  1988.         return errInvalidPatt;
  1989.     }
  1990.  
  1991.     switch ( gmpPlayMode )
  1992.     {
  1993.         case gmpPT:
  1994.             /* Calculate sampling rate: (assume PAL Amiga) */
  1995.             *rate = 3546895L / ((ulong) period);
  1996.             break;
  1997.  
  1998.         case gmpFT2:
  1999.             /* Check if we are using linear frequency table: */
  2000.             if ( gmpCurModule->playFlags.linFreqTable )
  2001.             {
  2002.                 /* Kool: */
  2003.                 *rate = gmpLinTable[period % 768] >> (period / 768);
  2004. //                Frequency = 8363*2^((6*12*16*4 - Period) / (12*16*4));
  2005.             }
  2006.             else
  2007.             {
  2008.                 *rate = 8363L * 1712L / ((ulong) period);
  2009.             }
  2010.             break;
  2011.  
  2012.         case gmpST3:
  2013.             *rate = 14317056L / ((ulong) period);
  2014.             break;
  2015.     }
  2016.  
  2017.     return OK;
  2018. }
  2019.  
  2020.  
  2021.  
  2022.  
  2023. /****************************************************************************\
  2024. *
  2025. * Function:     int gmpSetPeriod(unsigned period)
  2026. *
  2027. * Description:  Sets the playing period on current channel. Updates the
  2028. *               value in *gmpChan and sets it to Sound Device, taking
  2029. *               current period limits into account.
  2030. *
  2031. * Input:        unsigned period         new period value
  2032. *
  2033. * Returns:      MIDAS error code
  2034. *
  2035. \****************************************************************************/
  2036.  
  2037. int gmpSetPeriod(unsigned period)
  2038. {
  2039.     /* Skip if period is zero: */
  2040.     if ( period == 0 )
  2041.         return OK;
  2042.  
  2043.     /* Limit period value within current limits: */
  2044.     if ( period < gmpHandle->perLimitLow )
  2045.         period = gmpHandle->perLimitLow;
  2046.     if ( period > gmpHandle->perLimitUp )
  2047.         period = gmpHandle->perLimitUp;
  2048.  
  2049.     /* Set period value to channel: */
  2050.     gmpChan->period = period;
  2051.     gmpChan->realPeriod = period;
  2052.     return OK;
  2053. }
  2054.  
  2055.  
  2056.  
  2057.  
  2058. /****************************************************************************\
  2059. *
  2060. * Function:     int gmpChangePeriod(unsigned period)
  2061. *
  2062. * Description:  Changes the playing period on current channel. Sets the new
  2063. *               value to Sound Device, but does NOT update channel structure.
  2064. *
  2065. * Input:        unsigned period         new period value
  2066. *
  2067. * Returns:      MIDAS error code
  2068. *
  2069. \****************************************************************************/
  2070.  
  2071. int gmpChangePeriod(unsigned period)
  2072. {
  2073.     /* Limit period value within current limits: */
  2074.     if ( period < gmpHandle->perLimitLow )
  2075.         period = gmpHandle->perLimitLow;
  2076.     if ( period > gmpHandle->perLimitUp )
  2077.         period = gmpHandle->perLimitUp;
  2078.  
  2079.     gmpChan->realPeriod = period;
  2080.     return OK;
  2081. }
  2082.  
  2083.  
  2084.  
  2085.  
  2086. /****************************************************************************\
  2087. *
  2088. * Function:     int gmpSetVolume(int volume)
  2089. *
  2090. * Description:  Sets the playing volume on current channel. Sets the volume
  2091. *               to Sound Device and updates the channel structure, taking
  2092. *               current volume limits into account
  2093. *
  2094. * Input:        int volume              new playing volume (signed to allow
  2095. *                                       easier limit checking)
  2096. *
  2097. * Returns:      MIDAS error code
  2098. *
  2099. \****************************************************************************/
  2100.  
  2101. int gmpSetVolume(int volume)
  2102. {
  2103.     /* Limit volume: */
  2104.     if ( volume < 0 )
  2105.         volume = 0;
  2106.     if ( volume > (int) gmpHandle->volLimit )
  2107.         volume = gmpHandle->volLimit;
  2108.  
  2109.     /* Set volume to channel structure: */
  2110.     gmpChan->volume = volume;
  2111.  
  2112.     /* Set volume to Sound Device: */
  2113.     gmpChan->realVolume = volume;
  2114.     return OK;
  2115. }
  2116.  
  2117.  
  2118.  
  2119.  
  2120. /****************************************************************************\
  2121. *
  2122. * Function:     int gmpChangeVolume(int volume)
  2123. *
  2124. * Description:  Changes the playing volume on current channel. Sets the
  2125. *               volume to taking current volume limits into account, but
  2126. *               does NOT update channel structures.
  2127. *
  2128. * Input:        int volume              new playing volume (signed to allow
  2129. *                                       easier limit checking)
  2130. *
  2131. * Returns:      MIDAS error code
  2132. *
  2133. \****************************************************************************/
  2134.  
  2135. int gmpChangeVolume(int volume)
  2136. {
  2137.     /* Limit volume: */
  2138.     if ( volume < 0 )
  2139.         volume = 0;
  2140.     if ( volume > (int) gmpHandle->volLimit )
  2141.         volume = gmpHandle->volLimit;
  2142.  
  2143.     gmpChan->realVolume = volume;
  2144.  
  2145.     return OK;
  2146. }
  2147.  
  2148.  
  2149. /****************************************************************************\
  2150. *
  2151. * Function:     int gmpSetPanning(int panning)
  2152. *
  2153. * Description:  Sets the panning of current channel. Sets the panning
  2154. *               to Sound Device and updates the channel structure, taking
  2155. *               current panning limits into account
  2156. *
  2157. * Input:        int panning             new panning
  2158. *
  2159. * Returns:      MIDAS error code
  2160. *
  2161. \****************************************************************************/
  2162.  
  2163. int gmpSetPanning(int panning)
  2164. {
  2165.     int         error;
  2166.  
  2167.     switch ( gmpPlayMode )
  2168.     {
  2169.         case gmpFT2:
  2170.             if ( panning < 0 ) panning = 0;
  2171.             if ( panning > 255 ) panning = 255;
  2172.             break;
  2173.  
  2174.         default:
  2175.             /* Convert DMP-compatible panning value to MIDAS and set it to
  2176.                Sound Device: */
  2177.             if ( panning == 0xA4 )
  2178.                 panning = panSurround;
  2179.             else
  2180.                 panning -= 0x40;
  2181.  
  2182.             if ( (error = gmpSD->SetPanning(gmpChan->sdChannel, panning))
  2183.                 != OK )
  2184.                 PASSERROR(ID_gmpSetPanning)
  2185.             break;
  2186.     }
  2187.  
  2188.     DEBUGprintf("Set pan %i\n", (int) panning);
  2189.     gmpChan->panning = panning;
  2190.  
  2191.     return OK;
  2192. }
  2193.  
  2194. /****************************************************************************\
  2195. *
  2196. * Function:     int gmpNewNote(void)
  2197. *
  2198. * Description:  Plays the new note on the current channel
  2199. *
  2200. * Returns:      MIDAS error code
  2201. *
  2202. \****************************************************************************/
  2203.  
  2204. int gmpNewNote(void)
  2205. {
  2206.     int         error;
  2207.  
  2208.     /* Clear vibrato position: */
  2209.     gmpChan->vibPos = 0;
  2210.  
  2211.     /* Check if there is a valid instrument: */
  2212.     if ( (gmpChan->instrument != -1) && (gmpChan->sample != 0xFF) )
  2213.     {
  2214.         /* Check if the note is a key off command: */
  2215.         if ( gmpChan->note == 0xFE )
  2216.         {
  2217.             switch ( gmpPlayMode )
  2218.             {
  2219.                 case gmpFT2:
  2220.                     gmpChan->keyOff = 1;
  2221.                     gmpChan->volSustained = 0;
  2222.                     gmpChan->panSustained = 0;
  2223.  
  2224.                     if ( (gmpCurModule->instruments[gmpChan->instrument]
  2225.                             ->volEnvelope == NULL) &&
  2226.                         (!gmpChan->status.newInst) )
  2227.                             gmpSetVolume(0);
  2228.                     break;
  2229.  
  2230.                 case gmpST3:
  2231.                     if ( (error = gmpSD->StopSound(gmpChan->sdChannel)) != OK )
  2232.                         PASSERROR(ID_gmpNewNote)
  2233.  
  2234.                     break;
  2235.  
  2236.                 default:
  2237.                     /* Release sound: */
  2238.                     if ( (error = gmpSD->ReleaseSound(gmpChan->sdChannel)) != OK )
  2239.                         PASSERROR(ID_gmpNewNote)
  2240.  
  2241.                     /* Mark channel released: */
  2242.                     /* FIXME */
  2243.                     break;
  2244.             }
  2245.         }
  2246.         else
  2247.         {
  2248.             /*gmpChan->keyOff = 0;*/
  2249.             /* It would make sense to reset keyOff here, but it shouldn't
  2250.                be done - FT2 continues the fade out, for example, until
  2251.                a new instrument is set, even if there are new notes */
  2252.  
  2253.             gmpChan->prevNote = gmpChan->note;
  2254.  
  2255.             /* Set channel period to new note period: */
  2256.             if ( (error = gmpNotePeriod(gmpChan->note, &gmpChan->period))
  2257.                 != OK )
  2258.                 PASSERROR(ID_gmpNewNote)
  2259.  
  2260.             /* Retrig note - start playing with new period: */
  2261.             if ( (error = gmpPlayNote(gmpChan->period)) != OK )
  2262.                 PASSERROR(ID_gmpNewNote)
  2263.  
  2264.             /* Set playing position to startOffset if it has been
  2265.                 changed by a Sample Offset command: */
  2266.             if ( gmpChan->startOffset != 0 )
  2267.             {
  2268.                 if ( (error = gmpSD->SetPosition(gmpChan->sdChannel,
  2269.                     gmpChan->startOffset)) != OK)
  2270.                     PASSERROR(ID_gmpNewNote)
  2271.             }
  2272.         }
  2273.     }
  2274.  
  2275.     /* Mark there is no new note: */
  2276.     gmpChan->status.newNote = 0;
  2277.  
  2278.     return OK;
  2279. }
  2280.  
  2281.  
  2282.  
  2283.  
  2284. /****************************************************************************\
  2285. *
  2286. * Function:     int gmpSetSyncCallback(void (CALLING *musicSync)(unsigned syncNum, unsigned position, unsigned row))
  2287. *
  2288. * Description:  Sets music synchronization callback function. This function
  2289. *               will be called when the music synchronization command (command
  2290. *               W in FT2 and ST3) is encountered in the music. The function
  2291. *               receives as arguments the synchronization command infobyte,
  2292. *               current playing position position and current row number.
  2293. *               Note that the function will be called INSIDE THE PLAYER
  2294. *               TIMER INTERRUPT and thus SS != DS !!!
  2295. *
  2296. * Input:        gmpPlayHandle playHandle    playing handle
  2297. *               void (CALLING *SyncCallback)()  Pointer to music
  2298. *                                       synchronization callback function.
  2299. *                                       Set to NULL to disable callback
  2300. *
  2301. * Returns:      MIDAS error code
  2302. *
  2303. \****************************************************************************/
  2304.  
  2305. int CALLING gmpSetSyncCallback(gmpPlayHandle playHandle,
  2306.     void (CALLING *SyncCallback)(unsigned syncNum, unsigned position,
  2307.     unsigned row))
  2308. {
  2309.     playHandle->SyncCallback = SyncCallback;
  2310.  
  2311.     return OK;
  2312. }
  2313.  
  2314.  
  2315.  
  2316.  
  2317. /****************************************************************************\
  2318. *
  2319. * Function:     int gmpSetPosition(gmpPlayHandle playHandle, unsigned
  2320. *                   newPosition);
  2321. *
  2322. * Description:  Changes song playing position.
  2323. *
  2324. * Input:        gmpPlayHandle playHandle    playing handle
  2325. *               unsigned newPosition    new playing position
  2326. *
  2327. * Returns:      MIDAS error code
  2328. *
  2329. \****************************************************************************/
  2330.  
  2331. int CALLING gmpSetPosition(gmpPlayHandle playHandle, int newPosition)
  2332. {
  2333.     unsigned    oldPos = playHandle->position;
  2334.     int         pos, songLength;
  2335.     ushort      *song;
  2336.  
  2337.     song = playHandle->module->songData;
  2338.     songLength = (int) playHandle->module->songLength;
  2339.  
  2340.     pos = newPosition;
  2341.     if ( pos > songLength )
  2342.         pos = playHandle->restartPos;
  2343.     if ( pos < 0 )
  2344.         pos = songLength-1;
  2345.  
  2346.     /* Skip possible ST3 song filler entries: */
  2347.     if ( pos < (int) oldPos )
  2348.     {
  2349.         while ( (song[pos] == 0xFFFE) || (song[pos] == 0xFFFF) )
  2350.             if ( (--pos) < 0 )
  2351.                 pos = songLength-1;
  2352.     }
  2353.     else
  2354.     {
  2355.         while ( (song[pos] == 0xFFFE) || (song[pos] == 0xFFFF) )
  2356.             if ( (++pos) < 0 )
  2357.                 pos = playHandle->restartPos;
  2358.     }
  2359.  
  2360.     /* Start at the beginning of the new pattern: */
  2361.     playHandle->row = 0;
  2362.     playHandle->playPtr = NULL;
  2363.     playHandle->position = pos;
  2364.     playHandle->pattern = song[pos];
  2365.  
  2366.     return OK;
  2367. }
  2368.  
  2369. /*
  2370.  * $Log: gmplayer.c,v $
  2371.  * Revision 1.12  1997/01/16 18:41:59  pekangas
  2372.  * Changed copyright messages to Housemarque
  2373.  *
  2374.  * Revision 1.11  1997/01/16 18:30:31  pekangas
  2375.  * Fixed XM note fadeouts
  2376.  *
  2377.  * Revision 1.10  1997/01/07 19:18:15  pekangas
  2378.  * Fixed changing instrument w/o note in XMs
  2379.  *
  2380.  * Revision 1.9  1996/10/06 16:48:24  pekangas
  2381.  * Fixed an overflow problem in XM panning and added some checks
  2382.  *
  2383.  * Revision 1.8  1996/09/08 20:32:31  pekangas
  2384.  * gmpRunEnvelopes() no longer tries to set zero periods to SD
  2385.  *
  2386.  * Revision 1.7  1996/09/01 15:41:11  pekangas
  2387.  * Changed command handling for FT2 - all commands have now a separate old infobyte
  2388.  *
  2389.  * Revision 1.6  1996/07/16 20:25:09  pekangas
  2390.  * Removed Watcom C warnings
  2391.  *
  2392.  * Revision 1.5  1996/07/13 20:04:34  pekangas
  2393.  * Eliminated Visual C warnings
  2394.  *
  2395.  * Revision 1.4  1996/07/13 18:22:30  pekangas
  2396.  * Fixed to compile with Visual C
  2397.  *
  2398.  * Revision 1.3  1996/06/13 20:01:43  pekangas
  2399.  * Fixed a bug that crashed MIDAS if the song set tempo to 0
  2400.  *
  2401.  * Revision 1.2  1996/05/24 16:20:36  jpaana
  2402.  * Fixed to work with gcc
  2403.  *
  2404.  * Revision 1.1  1996/05/22 20:49:33  pekangas
  2405.  * Initial revision
  2406.  *
  2407. */
  2408.